package com.clz.mycustomview.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * canvas相关练习
 */
public class CanvasUseView extends View {
    public CanvasUseView(Context context) {
        super(context);
    }

    public CanvasUseView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CanvasUseView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setColor(Color.GREEN);
        paint.setStyle(Paint.Style.FILL);
        RectF rectF = new RectF(0, 0, 400, 200);
        // canvas.translate(100,100);
        //canvas.drawRect(rectF,paint);
        //verifyCanvasAndScreen(canvas);
        //canvasRotate(canvas);
        // canvasScale(canvas);
        //canvasSkew(canvas);
        //canvasClip(canvas);
        canvasSaveRestore(canvas);
    }

    /**
     * 测试canvas save restore
     */
    private void canvasSaveRestore(Canvas canvas) {
        canvas.drawColor(Color.RED);
        // 保存当前画布大小，即整屏
        canvas.save();
//        canvas.clipRect(new RectF(100, 100, 800, 800));
//        canvas.drawColor(Color.GREEN);
//        // 恢复整屏画布
//        canvas.restore();
//        canvas.drawColor(Color.BLUE);

        canvas.clipRect(new RectF(100,100,800,800));
        canvas.drawColor(Color.GREEN);
        // 保存的画布大小为Rect(100,100,800,800)
        canvas.save();

        canvas.clipRect(new RectF(200,200,700,700));
        canvas.drawColor(Color.BLUE);
        // 保存的画布大小为Rect(200,200,700,700)
        canvas.save();

        canvas.clipRect(new RectF(300,300,600,600));
        canvas.drawColor(Color.BLACK);
        // 保存的画布大小为Rect(300,300,600,600)
        canvas.save();


        canvas.clipRect(new RectF(400,400,500,500));
        canvas.drawColor(Color.WHITE);

        // 将栈顶的画布状态取出来，作为当前画布，并填充为黄色
        canvas.restore();
        canvas.drawColor(Color.YELLOW);
        // 连续3次出栈，将最后一次出栈的画布作为当前画布，并填充为黄色
        canvas.restore();
        canvas.restore();
        canvas.restore();
        canvas.drawColor(Color.YELLOW);
    }

    /**
     * 测试canvas缩放
     * float sx 水平方向伸缩的比例
     * float sy 垂直方向伸缩的比例
     */
    private void canvasScale(Canvas canvas) {
        Paint paint_green = generatePaint(Color.GREEN, Paint.Style.STROKE, 5);
        Paint paint_red = generatePaint(Color.RED, Paint.Style.STROKE, 5);
        Paint paint_yellow = generatePaint(Color.YELLOW, Paint.Style.STROKE, 5);

        Rect rect1 = new Rect(10, 10, 200, 100);
        canvas.drawRect(rect1, paint_green);

        canvas.scale(0.5f, 1);
        canvas.drawRect(rect1, paint_red);
    }

    /**
     * 测试画布扭曲
     * float sx 将画布在X轴方向上倾斜相应的角度，sx为倾斜角度的正切值
     * float sy 将画布在Y轴方向上倾斜相应的角度，sy为倾斜角度的正切值
     * 注意 这里都是倾斜角度的正切值，比如在x轴方向上倾斜60度，tan60 = 1.732
     */
    private void canvasSkew(Canvas canvas) {
        Paint paint_green = generatePaint(Color.GREEN, Paint.Style.STROKE, 5);
        Paint paint_red = generatePaint(Color.RED, Paint.Style.STROKE, 5);

        Rect rect1 = new Rect(10, 10, 200, 100);

        canvas.drawRect(rect1, paint_green);
        canvas.skew(1.732f, 0);//X轴倾斜60度，Y轴不变
        canvas.drawRect(rect1, paint_red);
    }

    /**
     * 裁减画布
     * 先把背景涂成红色，显示在屏幕上，然后裁减画布，最后将最新的画布涂成绿色，可见绿色部分
     * 只有一小块，而不是整个屏幕
     */
    private void canvasClip(Canvas canvas) {
        canvas.drawColor(Color.RED);
        canvas.clipRect(new RectF(100, 100, 200, 200));
        canvas.drawColor(Color.GREEN);
    }

    /**
     * 测试画布旋转
     */
    private void canvasRotate(Canvas canvas) {
        Paint greenPaint = generatePaint(Color.GREEN, Paint.Style.FILL, 5);
        Paint redPaint = generatePaint(Color.RED, Paint.Style.STROKE, 5);
        RectF rectF1 = new RectF(300, 10, 500, 100);
        canvas.drawRect(rectF1, redPaint);// 未旋转前
        canvas.rotate(30); // 顺时针旋转画布
        canvas.drawRect(rectF1, greenPaint);
    }

    /**
     * 验证屏幕显示与Canvas的关系
     * 结论: 每次调用drawXXX系列函数来绘图时，都会产生一个全新的透明图层，
     * 如果每次在调用drawXXXX系列函数前，调用平移，旋转等函数对Canvas进行了操作，
     * 那么这个操作是不可逆的。每次产生的画布的最新位置都是执行这些操作后的位置
     * 在Canvas图层与屏幕合成时，超出屏幕范围的图像是不会显示的
     */
    private void verifyCanvasAndScreen(Canvas canvas) {
        //构造2个画笔，一个红色，一个绿色
        Paint greenPaint = generatePaint(Color.GREEN, Paint.Style.STROKE, 3);
        Paint redPaint = generatePaint(Color.RED, Paint.Style.STROKE, 3);

        // 构造一个矩形
        RectF rectF1 = new RectF(0, 0, 400, 200);
        // 在平移画布前用绿色画笔画下边框
        canvas.drawRect(rectF1, greenPaint);
        // 在平移画布后，再用红色画笔重新画下边框
        canvas.translate(100, 100);
        canvas.drawRect(rectF1, redPaint);
    }

    private Paint generatePaint(int color, Paint.Style style, int width) {
        Paint paint = new Paint();
        paint.setColor(color);
        paint.setStyle(style);
        paint.setStrokeWidth(width);
        return paint;
    }
}
